# 万维网(World Wide Web, WWW)
万维网3项构建技术:
- 把标准通用标记语言作为页面的文本标记语言的
HTML
- 作为文档传递协议的
HTTP
- 指定文档所在地址的
URL
# HTTP
HTTP
(HyperText Transfer Protocol,超文本传输协议)是建立在TCP/IP
之上的应用层通信协议,它是TCP/IP
协议族的一个子集。 ——WebSocket
协议也是如此。
# 1. 因特网分层模型
五层模型:
(由下至上,从系统结构的角度)
层级 | 作用 | 包含常见协议 |
---|---|---|
物理层 | 规定网路物理介质(双绞线、电磁波等)的电气特性,作用是传送0和1的电信号(比特流) | |
数据链路层 | 确定0和1的分组方式(将电信号封装成帧) | 以太网协议、MAC地址、ARP协议 |
网络层 | 建立主机到主机的通信,IP寻址 | IP协议(1.为每台计算机分配IP地址;2.确定是否在同一子网络) |
传输层 | 建立端口到端口的通信 | TCP(传输控制协议,三次握手、四次挥手)、UDP(用户数据报文协议) |
应用层 | 规定应用程序的数据格式 | HTTP(超文本传输协议)、WebSocket、FTP(文本传输协议)、DNS(域名系统) |
越下面的层越靠近硬件,越上面的层越靠近用户。
(由上至下,从用户使用的角度,见彻底理解从输入URL到页面展现)
OSI七层模型:
应用层、表示层、会话层、传输层、网络层、数据链路层、物理层。
TCP/IP
协议族是互联网相关的各类协议的总称。
利用 TCP/IP
协议族进行网络通信时,会按照分层顺序,与对方进行通信。发送端从应用层往下走,接收端则从物理层往上走。
以 HTTP
为例:
- 首先作为发送端的客户端在应用层(
HTTP
协议)发出一个想看某个Web
页面的HTTP
请求。 - 接着,为了传输方便,在传输层(
TCP
协议)把从应用层处收到的数据(HTTP
请求报文)分割成报文段,并在各个报文段上打上标记序号后转发给网络层。 - 在网络层(
IP
协议),增加作为通信目的地的MAC
地址后转发给链路层。这样一来,发往网络的通信请求就准备齐全了。 - 接收端的服务器在链路层接收到数据,按序往上层发送,一直到应用层。当传输到应用层,才能算真正接收到由客户端发送过来的
HTTP
请求。
发送端在层与层之间传输数据时,每经过一层时必定会被打上一个该层所属的首部信息。反之,接收端在层与层传输数据时,每经过一层时会把对应的首部消去。
# 2. 相关协议及与HTTP
关系
DNS
-应用层:在发送端,提供域名到IP
地址之间的解析服务。HTTP
-应用层:在发送端,生成请求报文;在接收端,解析请求报文。TCP
-传输层:在发送端,将请求报文分割成报文段,并按顺序添加序号;在接收端,按序号以原来的顺序重组报文。此外,为确保数据正确传输,通过IP和端口号进行寻址,发送前会进行三次握手建立连接,发送后会进行四次挥手断开连接。IP
-网络层:使用ARP
协议,根据目标IP
地址和端口号查到对应的MAC
地址,并添加到报文上,然后将数据转交给数据链路层。再利用路由选择机制,经过若干次中转,最终将数据传输到目标服务器。
# 3. HTTP
的特点
无连接,即本次连接都只处理一个请求,请求结束就断开连接。为了实现长连接(或持久连接),http1.1引入了 keep-alive,允许一次 tcp 连接中进行多次http请求。
无状态,即每次请求都是独立的,不保存上次通信的状态。为了实现期望的保持状态功能,http1.1引入了
Cookie
技术。有了 Cookie 就可以携带并管理状态了。支持 C/S 和 B/S 模式。
简单快速。
灵活,支持传输任意类型的数据对象。数据类型由Content-type字段标识。
思考:设计成无状态,意在使得协议简单,且最初的web页面很简单、请求数很少。设计成无状态,一方面与最初的web页面简单有关,另一方面也是为了节省服务端存储和处理状态信息的内存开销。
解决无连接 —— 持久连接
为了解决 http1.0 每次通信都要建立、断开 TCP 连接的问题,http1.1新增了持久连接,持久连接的特点是:只要任意一端没有明确提出断开连接(必须两方都提出断开),则保持 TCP 连接状态。可实现建立1次 TCP 连接后,进行多次请求和响应通信。
http1.1 默认都是持久连接。请求或响应的头部添加 Connection: keep-alive
告知对方开启或维持持久连接,当一方希望断开连接时,将值改为 Connection: close
。
此外,通过 Keep-Alive: timeout=15, max=100
来控制持久连接的超时时间和最大 http 请求数。
持久连接使得管线化成为可能,开启管线化后,可实现同时并行发送多个请求,不再需要一个接一个发送请求。浏览器通常默认不开启管线化,而浏览器(chrome)支持同时发送6个请求,并非管线化机制,而是创建了6个网络线程,每个线程建立一个TCP连接。(详见http1.0与http1.1区别)
解决无状态 —— Cookie
Cookie 技术通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态。
Cookie 中的字段及含义:
- Name - 字段名
- Value - 字段值
- Expires - 该 Cookie 字段的有效期(默认浏览器关闭时失效)
- Domain - 该 Cookie 字段适应的域名
- Path - 该 Cookie 字段适应的文件目录(默认文档所在目录)
- Secure - 仅在https安全通信时发送该 Cookie 字段
- HttpOnly - 仅在网络请求中发送,不能被js脚本获取
- SameSite - 限制第三方页面访问目标网站时携带 Cookie 字段
Cookie 传递过程:
- 服务端生成 Cookie,放入响应报文的
Set-Cookie
字段中 - 客户端收到带有
Set-Cookie
字段的响应报文后,保存 Cookie 信息 - 再次发送请求时,客户端自动将 Cookie 信息放入请求头中的
Cookie
字段中 - 服务端收到带有
Cookie
字段的请求报文后,可获知请求来源、之前的状态等信息。
# 4. 常用请求方法
# 5. 常见状态码
状态码 原因 | 含义 |
---|---|
101 Switching Protocols | 切换协议(websocket使用http建立连接) |
200 OK | 请求已成功处理 |
204 No Content | 请求已成功处理,但无数据返回(比如提交数据,但无需返回数据的场景) |
206 Partial Content | 范围请求已成功处理,返回范围内的数据 |
301 Moved Permanently | 永久重定向,浏览器自动跳转到返回的新的地址(缓存并自动请求新地址、爬取新页面删除旧页面) |
302 Found | 临时重定向,浏览器自动跳转到返回的新的地址(不缓存且依然请求旧页面、爬取新页面但仍保留旧页面) |
304 Not Modified | 服务端已经执行了GET,但文件未变化,可使用浏览器缓存 |
400 Bad Request | 无法理解该请求 |
401 Unauthorized | 未认证 |
403 Forbidden | 未授权(特定资源) |
404 Not Found | 未找到请求的资源 |
500 Internal Server Error | 服务器内部错误 |
501 Not Implemented | 请求方法不被服务器支持 |
503 Service Unavailable | 服务器不可用 |
301(永久重定向) 和 302(临时重定向) 的区别?
定义。301被请求的资源已永久移动到新位置,再次请求时自动使用本请求返回的url。302被请求的资源临时移动到新位置,再次请求时还是以该url发起请求。
缓存。301默认开启缓存,302默认不开启(除非指定Cache-Control或Exprise)。
搜索引擎。301时搜索引擎会认为老url已失效,会爬取新url内容并保存新url。302时搜索引擎会认为老url未失效,会爬取新url内容,但保存老url地址,当收录的指向新url的地址较多时,搜索引擎会认为是恶意处理从而会对该网站降权。
共同点:都会在响应头中添加
Location: 新的URL
,并让客户端以 GET 方式请求新的URL。
401(未认证) 和 403(未授权) 的区别?
- 401未认证(未注册)是服务器针对用户身份的要求,类比注册用户身份。
- 403未授权是指当前身份的用户无权请求特定资源,类比爱奇艺普通用户无权观看vip视频。
# HTTPS
# 1. HTTP 存在的问题:
- 内容窃听。采用明文(不加密)通信,内容可能会被窃听。
- 身份伪装。不验证对方的身份,有可能遭遇身份伪装。
- 数据篡改。无法验证数据的完整性,报文可能被篡改。
# 2. 什么是 HTTPS?
HTTPS = HTTP + SSL/TLS = HTTP + 加密 + 证书 + 完整性保护
HTTPS 并非是应用层的一种新协议,它是身披 SSL 外壳的 HTTP。只是将 HTTP 的通信接口用 SSL(Secure Socket Layer, 安全套接层)或 TLS(Transport Layer Security, 安全传输层协议)代替而已。
通常,HTTP 直接和 TCP 通信。当使用 SSL 时,则演变成先和 SSL 通信,再由 SSL 和 TCP 通信了。简言之,所谓 HTTPS,其实就是身披 SSL 协议这层外壳的 HTTP。
在采用 SSL 后,HTTP 就拥有了 HTTPS 的加密(内容窃听)、证书(身份伪造)和完整性保护(数据篡改)这些功能。
TLS 是更为安全的升级版 SSL。由于 SSL 是更为常用的术语,因此常将安全证书统称为 SSL 证书。
# 3. 默认端口
http - 80、https - 443
# 4. 加密方式
- 对称加密
加密和解密使用同一个密钥。
过程:通信双方使用同一个密钥,一方用该密钥加密,另一方用该密钥解密。
优点:加密解密性能较高。
缺点:在将密钥发送给对方时,存在被窃取密钥的可能,而一旦密钥被窃取,加密就失去了意义。
- 非对称加密
公钥(公开密钥)和私钥(私有密钥)配对使用。公钥可发给任何人,用以加密信息;私钥不能给任何人,用以解密信息。
过程:发送信息的一方使用对方的公钥进行加密处理,对方收到加密后的信息后,使用自己的私钥进行解密。也就是,通信双方各自有一对公钥和私钥,并将自己的公钥给到对方。
优点:仅告知对方用于加密的公钥,而用于解密的私钥不会被窃取,安全性较高。
缺点:解密过程(是在对离散对数进行求值)性能较低,比较耗时。
- 混合加密机制(HTTPS)
对称加密性能高,但难点在于如何将密钥安全地告知对方,而非对称加密安全性高,可以实现安全告知密钥。所以,https结合了二者的优点,即:
- 非对称加密:发送方使用接收方的公钥对密钥进行加密,对方收到后使用自己的私钥对其进行解密,得到用于对称加密的密钥。
- 对称加密:得到密钥后,使用对称加密方式进行通信。
# 5. https通信过程
前置条件:
a. 网站向证书颁发机构提供公钥,机构用自己的私钥加密网站的公钥,并加上数字签名,生成公钥数字证书
提供给网站;
b. 浏览器中预先内嵌了证书颁发机构的公钥。
- TCP三次握手建立连接
SSL加密握手(非对称加密通信)
SSL握手是在TCP握手之后进行的
- C -> S:发送客户端支持的加密组件列表、SSL版本
- S -> C:选择一种服务端也支持的加密组件。发送加密组件和
公钥数字证书
- C -> S:通过浏览器内置的机构公钥验证服务端身份,并获得服务端的公钥。生成密钥,并用公钥加密。发送加密后的密钥。
- S:通过私钥解密加密后的密钥,获得密钥。
开始HTTP通信(对称加密通信)
- C -> S:用密钥对请求加密,发送请求
- S -> C:用密钥对请求解密,用密钥对响应加密,发送响应
- C:用密钥对响应解密
TCP四次挥手断开连接
# 常见比较
# URI 与 URL 的区别
- URI 统一资源标识符,可以理解为表示的就是某个资源。
- URL 统一资源定位符,表示的是资源在互联网中的地址。
# TCP 与 UDP 的区别和使用场景
# 什么是 quic,它基于 UDP 如何保证可靠性
# cookie、session 与 token 的区别
Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。
Cookie存放在硬盘中。为了获得更高的存取速度,服务器一般把Session放在内存里。
Session是服务器端使用的一种记录客户端状态的机制,使用上比Cookie简单一些,相应的也增加了服务器的存储压力。客户端访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上,这就是Session。如果说Cookie机制是通过检查客户身上的“通行证”来确定客户身份的话,那么Session机制就是通过检查服务器上的“客户明细表”来确认客户身份。Session相当于在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了。
cookie中存放的是例如jgbsessid字段,是“客户明细表”中Session的id,有了该id,服务端才能查找对应的Session数据。Session是会话级别的,因此同一机器的两个浏览器窗口访问服务器时,会生成两个不同的Session。
- session 是由服务端针对当前会话,生成的一个随机数,通常放在cookie中发送给客户端,并存储在服务器的session列表中。客户端发送请求时cookie中携带session的id。服务器收到 cookie 后解析出 sessionId,再去 session 列表中查找,若能查到则匹配成功。
- cookie 是由服务端生成,用于传输用户信息,存储在客户端,请求中会自动添加。
- token 是由服务端根据用户id、用户名、定义好的密钥、过期时间生成的签名令牌,通常存放在客户端的localStroage,请求时手动添加在请求头中,服务器收到 token 后解密就可知道是哪个用户。与session相比,不需要存储在服务端,是用计算性能换取存储空间的方案,服务器的横向扩展性更好。同时,也是CSRF(跨站请求伪造)的解决方案。
参考
如何区分不同用户——Cookie/Session机制详解 (opens new window) 彻底理解cookie,session,token (opens new window)
彻底弄懂session,cookie,token (opens new window)
# http1.0与http1.1区别
http1.1 是目前主流的http协议版本
- 缓存方式:1.0 用 Expires、Last-Modified、If-Modified-Since;1.1使用 Cache-Control、Etag、If-None-Match。详见http缓存机制 (opens new window)
- 请求体优化:HTTP1.1在请求头引入了 range 字段,它允许只请求资源的某个部分
- 长连接:1.0中每个请求都要进行tcp连接,而1.1中引入长连接(Connection: keep-alive 默认开启,可通过设置nginx或apache服务器实现),建立一个tcp连接通道后,一定时间内可以发送多次http请求。注:长连接实现的是一次连接可发送多个请求,但这个“多个”是串行的,而我们从浏览器network中看到的同域名请求最多同时发送6个http请求,是浏览器开启了多个网络线程(每个线程都建立一个tcp连接)实现的,并非http1.1实现了并行,也就是说第7个请求有可能与第1个请求用的是同一个连接(二者串行关系),但第1个和第2个很可能是两个不同的连接(分属于两个网络线程)。
# http2与http1.x区别
http1.1还存在的问题:长连接只是解决了多次连接的问题,并没有真正实现并行传输(虽然浏览器的多线程可并行请求,但是要为每个线程建立一个tcp连接)。
为了解决上述问题,http2.0引入二进制数据帧
和二进制数据流
的概念,实现多路复用。帧负责对数据进行序列标识,以确保接收并行流数据后可按顺序重新组装。流负责数据的并行传输,同一域名下所有请求,不管请求数有多少,都只建立一个tcp连接,然后基于流进行并行传输。
有了这个特性,之前我们的两个性能优化方式就没有必要了:1. 静态资源合并;2. 多域名提高下载速度。
区别可概括为:
- 二进制分帧;
- 多路复用/连接共享;
- 头部压缩;
- 服务端推送。
注意:浏览器6个请求限制,是指浏览器对同一个域名最多开启6个线程,即建立6个tcp连接。而多路复用是指在同一个tcp连接中,通过二进制分帧交错或按优先级发送多个请求的数据,然后在服务端分别组合起来,可以同时请求所有请求。
# GET 与 POST 区别
GET 和 POST 是 HTTP 的两种请求方式,HTTP 是基于 TCP/IP 的应用层协议,也就是说二者使用的是相同的传输层协议,所以,在传输上二者没有本质区别。 二者的区别主要有以下几点:
- 报文格式的规范约定。GET 参数应放在 URL 上,而 POST 参数应该放在请求体中。但这只是规范约定,而非 TCP 的要求,所以,只要服务端支持,我们也可以将 GET 参数写在请求体,将 POST 参数写在 URL 上。
- 参数的大小限制。HTTP协议没有body和url的长度限制,这些限制大多是浏览器和服务器的原因。GET 的 URL 通常被限定在几K范围内。
- 安全性。Post相较于Get是稍微安全一些的,因为数据在地址栏是不可见的。然后,从传输的角度来说,他们都是不安全的,因为HTTP在网络上都是明文传输的,只要在网络节点上捉包,就能完整的获取数据报文。想要安全的传输,就只有加密,使用HTTPS。
- 发送数据包次数。有些浏览器会将 POST 的 header 和 body 分开发送,服务端返回100状态码再发送body。但实践发现 Chrome 并非如此。
- 缓存。大多数浏览器 GET 请求是默认开启缓存的,而 POST 需手动设置。
# POST 与 PUT 区别
- HTTP方法的幂等性是指一次和多次请求某一个资源应该具有同样的副作用。
- POST和PUT的区别容易被简单地误认为“POST表示创建资源,PUT表示更新资源”;而实际上,二者均可用于创建资源,更为本质的差别是在幂等性方面。
- POST所对应的URI并非创建的资源本身,而是资源的接收者。比如:POST http://www.forum.com/articles 的语义是在 http://www.forum.com/articles 下创建一篇帖子,HTTP响应中应包含帖子的创建状态以及帖子的URI。两次相同的POST请求会在服务器端创建两份资源,它们具有不同的URI;所以,POST方法不具备幂等性。而PUT所对应的URI是要创建或更新的资源本身。比如:PUT http://www.forum/articles/4231 的语义是创建或更新ID为4231的帖子。对同一URI进行多次PUT的副作用和一次PUT是相同的;因此,PUT方法具有幂等性。
# 常见 http 报文解析
参考: